package com.han.verifycode.utils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.han.verifycode.data.ArrayData;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StrUtil {
    private static final ObjectMapper mapper = new ObjectMapper();
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

    static {
        mapper.registerModule(javaTimeModule());
    }

    public static ObjectMapper getMapper() {
        return mapper;
    }

    /**
     * 生成随机字符串
     *
     * @return
     */
    public static String generateRandomCode() {
        return UUID.randomUUID().toString();
    }


    /**
     * 对时间解析格式的定义
     *
     * @return 时间格式解析
     */
    public static JavaTimeModule javaTimeModule() {

        final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT);
        final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm:ss");

        JavaTimeModule timeModule = new JavaTimeModule();

        timeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));
        timeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter));
        timeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(timeFormatter));

        timeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter));
        timeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter));
        timeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(timeFormatter));

        return timeModule;
    }


    /**
     * 对象转换成json
     *
     * @param obj 对象
     * @return json字符串
     */
    public static String json(Object obj) {
        try {
            return mapper.writeValueAsString(obj);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 对象转成格式化的json串
     *
     * @param obj 对象
     * @return 格式化的json串
     */
    public static String prettyJson(Object obj) {
        try {
            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * json串转JAVA对象
     *
     * @param content   json串
     * @param valueType java类型
     * @param <T>       类型变量
     * @return 对象
     */
    public static <T> T parse(String content, Class<T> valueType) {
        try {
            return mapper.readValue(content, valueType);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * json串转JAVA对象
     *
     * @param content   json串
     * @param valueType java类型
     * @param <T>       类型变量
     * @return 对象
     */
    public static <T> T parse(String content, TypeReference<T> valueType) {
        try {
            return mapper.readValue(content, valueType);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 判断字符串中是否包含中文
     *
     * @param str 待校验字符串
     * @return 是否为中文
     * @warn 不能校验是否为中文标点符号
     */
    public static boolean isContainChinese(String str) {
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(str);
        if (m.find()) {
            return true;
        }
        return false;
    }

    /**
     * 获取随机的成语
     *
     * @param file 数据源
     * @return
     */
    public static String getRandomIdiom(String file) {
        InputStream input = FileUtil.getFile(file);
        ObjectMapper mapper = StrUtil.getMapper();
        ArrayData re = null;
        try {
            re = mapper.readValue(input, new TypeReference<ArrayData<String>>() {
            });
        } catch (IOException e) {
            e.printStackTrace();
        }
        List<String> s = re.getArrays();
        int index = RandomUtil.getRandom().nextInt(s.size() - 1);

        return s.get(index);
    }

    /**
     * 获取当前日期字符串
     *
     * @return
     */
    public static String getDateStr() {
        LocalDateTime time = LocalDateTime.now();
        DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern(DEFAULT_DATE_FORMAT);
        String re = dtf2.format(time);
        return re;
    }

    /**
     * 判断字符串是否为空
     *
     * @param s
     * @return
     */
    public static boolean isEmpty(String s) {
        return s == null || s.length() == 0 || s.trim().length() == 0;
    }


    /**
     * 打乱字符串
     */
    public static String shuffle(String content) {
        List<String> ss = Stream.of(content.split("")).collect(Collectors.toList());
        Collections.shuffle(ss);
        String result = String.join("", ss);
        while (result.equals(content)) {
            Collections.shuffle(ss);
            result = String.join("", ss);
        }
        return result;
    }


}
